Introduction to Regular Expressions Using re in Python
Course: Python Training
Topic: Introduction to Regular Expressions Using re
Course Link: Python Training Course – JustAcademy
Demo Link: Register for a Course Demo
Website: JustAcademy Official Website
1. Introduction to Regular Expressions
A regular expression (regex or regexp) is a sequence of characters that defines a search pattern. Regular expressions are used to search, match, extract, validate, split, and replace text according to specific rules.
Python provides the built-in re module for working with regular expressions. It is useful when processing text files, cleaning datasets, extracting information from logs, validating input formats, and finding patterns in large strings.
Example: Finding a Word in Text
import re
text = "Python makes text processing easier."
pattern = r"Python"
result = re.search(pattern, text)
if result:
print("Match found:", result.group())
else:
print("No match found")
Output
Match found: Python
In this example, re.search() searches for the pattern Python anywhere in the input string and returns a match object if the pattern is found.
2. Why Use Regular Expressions?
Regular expressions help developers process text without writing extensive loops and conditional statements for every possible character combination.
- Search for particular words or character sequences.
- Extract numbers, dates, email-like strings, identifiers, and other patterns.
- Check whether text follows a required format.
- Replace unwanted characters or repeated text.
- Split text using patterns such as commas, spaces, or multiple delimiters.
- Analyze application logs, documents, and text-based datasets.
Common Applications
| Application |
Example |
| Data cleaning |
Remove unnecessary spaces or symbols. |
| Input validation |
Check whether a value contains the expected characters. |
| Log analysis |
Extract error codes and timestamps. |
| Text extraction |
Find numbers or identifiers in documents. |
| Search and replace |
Replace repeated spaces with a single space. |
| Text parsing |
Separate text using different delimiters. |
3. Importing the re Module
The re module is included in Python's standard library, so it does not need to be installed separately.
import re
text = "Learn Python Regular Expressions"
pattern = r"Python"
if re.search(pattern, text):
print("Python is present")
The import re statement makes the regular-expression functions available to the program.
4. Understanding Regex Patterns and Raw Strings
A regex pattern describes the characters or structure that Python should look for. Patterns can contain ordinary characters, special symbols, character classes, quantifiers, groups, and other constructs.
It is generally recommended to write regex patterns as raw strings by adding the letter r before the quotation mark.
Example
import re
pattern = r"\d+"
text = "There are 25 students in the class."
print(re.findall(pattern, text))
Output
['25']
The raw string r"\d+" represents a regex pattern that matches one or more digits. Raw strings help prevent confusion between Python string escaping and regex escaping.
5. Basic Characters and Metacharacters
Most ordinary characters match themselves. However, certain characters have special meanings in regex patterns. These are known as metacharacters.
| Metacharacter |
Meaning |
Example |
. |
Matches any character except a newline by default. |
c.t matches cat and cut. |
^ |
Matches the beginning of a string, or a line in multiline mode. |
^Hello |
$ |
Matches the end of a string, or a line in multiline mode. |
end$ |
* |
Matches zero or more repetitions of the preceding expression. |
ab* matches a, ab, abb. |
+ |
Matches one or more repetitions. |
\d+ |
? |
Matches zero or one repetition. |
colou?r |
{m,n} |
Matches between m and n repetitions. |
\d{2,4} |
[] |
Defines a character set. |
[aeiou] |
() |
Groups expressions and captures matched text. |
(ab)+ |
| |
Matches either alternative. |
cat|dog |
\ |
Introduces a special sequence or escapes a metacharacter. |
\. matches a literal period. |
6. Character Classes and Special Sequences
Character classes specify which characters may appear at a particular position in a match. Special sequences provide convenient shortcuts for common character types and positions.
| Pattern |
Meaning |
Example |
\d |
A Unicode decimal digit by default in string patterns. |
\d+ matches 123. |
\D |
A character that is not a decimal digit. |
\D+ |
\w |
A word character, generally Unicode alphanumeric characters or underscore. |
\w+ |
\W |
A character that is not a word character. |
\W+ |
\s |
A whitespace character. |
\s+ |
\S |
A non-whitespace character. |
\S+ |
\b |
A word boundary. |
\bcat\b |
\B |
A position that is not a word boundary. |
\Bcat |
\A |
The start of the entire string. |
\AHello |
\Z |
The end of the string. |
end\Z |
Note: In Python string patterns, \d, \w, and related classes have Unicode-aware behavior by default. Use the re.ASCII flag when ASCII-only behavior is required.
Example: Extracting All Numbers
import re
text = "Order 102 contains 4 items and costs 750 rupees."
numbers = re.findall(r"\d+", text)
print(numbers)
Output
['102', '4', '750']
7. Character Sets and Ranges
Square brackets define a character set. The regex matches one character from the specified set at that position.
import re
text = "cat cot cut cet"
matches = re.findall(r"c[aeiou]t", text)
print(matches)
Output
['cat', 'cot', 'cut', 'cet']
The pattern [aeiou] matches one vowel from the specified set.
Using Ranges
import re
text = "A1 B2 C3 D4"
print(re.findall(r"[A-Z]", text))
print(re.findall(r"[0-9]", text))
Output
['A', 'B', 'C', 'D']
['1', '2', '3', '4']
Common ranges include [a-z] for lowercase ASCII letters, [A-Z] for uppercase ASCII letters, and [0-9] for digits.
Negated Character Sets
import re
text = "abc123!"
print(re.findall(r"[^0-9]", text))
Output
['a', 'b', 'c', '!']
When ^ appears first inside a character set, it matches characters that are not included in that set.
8. Quantifiers: Repeating a Pattern
Quantifiers specify how many times the preceding character or group can appear.
| Quantifier |
Meaning |
Example |
* |
Zero or more repetitions. |
ab* matches a, ab, abb. |
+ |
One or more repetitions. |
ab+ matches ab and abb, but not a. |
? |
Zero or one repetition. |
colou?r matches color and colour. |
{3} |
Exactly three repetitions. |
\d{3} |
{2,5} |
Between two and five repetitions. |
\d{2,5} |
{4,} |
Four or more repetitions. |
[A-Z]{4,} |
Example: Matching a Four-Digit Code
import re
codes = ["1234", "567", "12345"]
for code in codes:
if re.fullmatch(r"\d{4}", code):
print(code, "is valid")
else:
print(code, "is invalid")
Output
1234 is valid
567 is invalid
12345 is invalid
9. Greedy and Non-Greedy Matching
Quantifiers such as * and + are greedy by default: they attempt to match as much text as possible while allowing the overall pattern to succeed. Adding ? after a quantifier makes it non-greedy, so it tries to match as little text as possible.
import re
text = "<b>First</b> and <b>Second</b>"
print(re.findall(r"<.*>", text))
print(re.findall(r"<.*?>", text))
Output
['<b>First</b> and <b>Second</b>']
['<b>', '</b>', '<b>', '</b>']
The first pattern consumes the longest possible span between angle brackets that satisfies the expression. The second finds each individual tag-like bracketed segment. Regex is not a complete parser for HTML; use an HTML parser when working with real HTML documents.
10. Important Functions in the re Module
The re module provides several functions for different text-processing tasks. Choosing the correct function helps make patterns easier to understand.
| Function |
Purpose |
Typical Use |
re.search() |
Finds the first match anywhere in the string. |
Searching for a keyword. |
re.match() |
Checks for a match at the beginning of the string. |
Checking a prefix. |
re.fullmatch() |
Requires the entire string to match the pattern. |
Checking a complete input format. |
re.findall() |
Returns all non-overlapping matches in a list. |
Extracting numbers or words. |
re.finditer() |
Returns an iterator of match objects. |
Processing matches with positions. |
re.sub() |
Replaces matches with replacement text. |
Cleaning text. |
re.split() |
Splits text wherever the pattern matches. |
Splitting on several delimiters. |
re.compile() |
Creates a reusable compiled pattern object. |
Using one pattern repeatedly. |
11. Using re.search()
re.search() scans the string and returns the first matching location. It returns a match object when successful and None when no match is found.
import re
text = "My employee ID is EMP245."
match = re.search(r"EMP\d+", text)
if match:
print("Found:", match.group())
print("Start:", match.start())
print("End:", match.end())
else:
print("No employee ID found")
Output
Found: EMP245
Start: 20
End: 26
The group() method returns the matched text. The start() and end() methods provide the match's start and end positions, where the end position is exclusive.
12. Using re.match()
re.match() checks only from the beginning of the string. It does not scan forward to find a later match.
import re
print(re.match(r"Python", "Python is easy"))
print(re.match(r"Python", "Learn Python"))
The first call returns a match object because the text begins with Python. The second returns None because the string begins with Learn.
13. Using re.fullmatch()
re.fullmatch() succeeds only if the entire string matches the pattern. It is often useful for validating simple formats.
import re
values = ["AB123", "A123", "AB1234"]
for value in values:
if re.fullmatch(r"[A-Z]{2}\d{3}", value):
print(value, "matches the format")
else:
print(value, "does not match the format")
Output
AB123 matches the format
A123 does not match the format
AB1234 does not match the format
This pattern requires exactly two uppercase ASCII letters followed by exactly three digits. Format matching alone does not establish that an identifier is genuine or authorized.
14. Using re.findall()
re.findall() returns all non-overlapping matches as a list. If the pattern contains capturing groups, the returned items may be strings or tuples depending on the number of groups.
import re
text = "Prices: 120, 450, 999"
prices = re.findall(r"\d+", text)
print(prices)
Output
['120', '450', '999']
Example: Extracting Words
import re
text = "Python regex is useful"
words = re.findall(r"\b\w+\b", text)
print(words)
Output
['Python', 'regex', 'is', 'useful']
15. Using re.finditer()
re.finditer() returns an iterator that produces match objects for each non-overlapping match. It is useful when both the matched text and its position are needed.
import re
text = "Item 12, Item 34, Item 56"
for match in re.finditer(r"\d+", text):
print("Value:", match.group(), "Position:", match.start())
Output
Value: 12 Position: 5
Value: 34 Position: 14
Value: 56 Position: 23
16. Using re.sub() for Replacing Text
re.sub() replaces occurrences that match a pattern with a replacement string. It is commonly used for text cleaning and normalization.
Example: Replacing Multiple Spaces
import re
text = "Python is easy to learn"
cleaned = re.sub(r"\s+", " ", text)
print(cleaned)
Output
Python is easy to learn
Example: Removing Non-Digit Characters
import re
phone = "+91 98765-43210"
digits_only = re.sub(r"\D", "", phone)
print(digits_only)
Output
919876543210
This operation extracts digits; it does not validate whether the resulting value is a valid or reachable phone number.
17. Using re.split()
re.split() splits a string at every match of the specified pattern. It is useful when text contains multiple separators.
import re
text = "apple,banana;orange mango"
items = re.split(r"[,;\s]+", text)
print(items)
Output
['apple', 'banana', 'orange', 'mango']
The pattern [,;\s]+ matches one or more commas, semicolons, or whitespace characters.
18. Capturing Groups
Parentheses create capturing groups. They let you retrieve specific portions of a match separately.
import re
text = "Date: 22-10-2026"
pattern = r"(\d{2})-(\d{2})-(\d{4})"
match = re.search(pattern, text)
if match:
print("Full match:", match.group(0))
print("Day:", match.group(1))
print("Month:", match.group(2))
print("Year:", match.group(3))
print("All groups:", match.groups())
Output
Full match: 22-10-2026
Day: 22
Month: 10
Year: 2026
All groups: ('22', '10', '2026')
Group zero represents the entire match. Capturing groups are numbered from one in the order of their opening parentheses.
19. Non-Capturing and Named Groups
A non-capturing group, written as (?:...), groups part of a pattern without storing it as a captured result. A named group, written as (?P<name>...), assigns a descriptive name to a captured portion.
Non-Capturing Group Example
import re
text = "color colour"
matches = re.findall(r"colou?r", text)
print(matches)
Named Group Example
import re
text = "Order ID: ORD582"
match = re.search(
r"Order ID: (?P<prefix>[A-Z]+)(?P<number>\d+)",
text
)
if match:
print(match.group("prefix"))
print(match.group("number"))
print(match.groupdict())
Output
ORD
582
{'prefix': 'ORD', 'number': '582'}
Named groups can improve readability in patterns that extract several fields from structured text.
20. Alternation and Word Boundaries
The alternation operator | matches one alternative or another. Word boundaries help prevent matching a word as only part of a larger word.
Example: Matching Several Keywords
import re
text = "Python, Java, and JavaScript are programming languages."
matches = re.findall(r"Python|JavaScript|Java", text)
print(matches)
Output
['Python', 'Java', 'JavaScript']
To match complete words, use word boundaries:
import re
text = "Java and JavaScript are different names."
print(re.findall(r"\bJava\b", text))
Output
['Java']
Ordering alternatives carefully can matter because the regex engine tries alternatives from left to right. Word boundaries are helpful when whole-word matching is intended.
21. Regex Flags
Flags change how a pattern behaves. They can be supplied as arguments to functions or when compiling a pattern.
| Flag |
Purpose |
re.IGNORECASE or re.I |
Performs case-insensitive matching. |
re.MULTILINE or re.M |
Makes ^ and $ work at line boundaries as well as string boundaries. |
re.DOTALL or re.S |
Allows . to match newline characters. |
re.VERBOSE or re.X |
Allows whitespace and comments in a pattern, outside character classes and escaped sequences. |
re.ASCII or re.A |
Restricts several character classes to ASCII behavior. |
Example: Case-Insensitive Search
import re
text = "Python PYTHON python"
matches = re.findall(r"python", text, re.IGNORECASE)
print(matches)
Output
['Python', 'PYTHON', 'python']
Example: Multiline Matching
import re
text = "Python is easy.\nJava is popular."
matches = re.findall(r"^(\w+)", text, re.MULTILINE)
print(matches)
Output
['Python', 'Java']
22. Compiling Regular Expressions
re.compile() converts a pattern into a reusable regular-expression object. This can make code easier to organize when the same pattern is applied repeatedly.
import re
email_pattern = re.compile(r"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}")
emails = [
"[email protected]",
"invalid-email",
"[email protected]"
]
for email in emails:
if email_pattern.fullmatch(email):
print(email, "matches the basic pattern")
else:
print(email, "does not match the basic pattern")
This is a basic pattern for demonstration, not a complete implementation of all valid email-address rules. For many ordinary inputs, the pattern can identify an email-like format, but it does not verify that an address exists or can receive mail.
23. Practical Example: Extracting Email-Like Strings
The following example demonstrates how to find simple email-like strings in a paragraph. Real-world email validation can be more complex than a single regex.
import re
text = """
Contact support at [email protected].
For sales, write to [email protected].
"""
pattern = r"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}"
emails = re.findall(pattern, text)
for email in emails:
print(email)
Output
[email protected]
[email protected]
This approach is useful for basic text extraction. Applications that accept user registrations should use suitable validation and verification processes rather than relying solely on a regex.
24. Practical Example: Cleaning Text Data
Regular expressions are useful for standardizing text before analysis. The following example removes extra spaces and unwanted punctuation while preserving letters, digits, and whitespace.
import re
text = " Hello!!! Python @ 2026... "
text = re.sub(r"[^\w\s]", "", text)
text = re.sub(r"\s+", " ", text).strip()
print(text)
Output
Hello Python 2026
The first substitution removes characters that are neither word characters nor whitespace. The second replaces repeated whitespace with a single space and removes whitespace at the beginning and end.
25. Common Errors and Troubleshooting
| Problem |
Cause |
Solution |
| Pattern returns no match |
The input does not satisfy the specified pattern. |
Inspect the pattern and input carefully, including capitalization and spaces. |
| Backslash behaves unexpectedly |
Python string escaping conflicts with regex escaping. |
Use raw strings such as r"\d+". |
| Too much text is matched |
A greedy quantifier consumes a large matching span. |
Consider a non-greedy quantifier or a more precise character class. |
| Only the first match appears |
re.search() returns only the first match. |
Use findall() or finditer() when all matches are needed. |
| Partial input is accepted |
The pattern is being searched for rather than required to match the entire input. |
Use re.fullmatch() for complete-string matching. |
| Invalid regex syntax |
Parentheses, brackets, or quantifiers may be malformed. |
Check grouping, escaping, and quantifier syntax. |
| Unexpected Unicode matches |
Character classes may match Unicode characters by default. |
Use re.ASCII if ASCII-only behavior is required. |
26. Best Practices for Writing Regular Expressions
- Use raw strings for most regex patterns.
- Choose the correct operation:
search(), match(), fullmatch(), findall(), or another suitable function.
- Prefer readable patterns over overly complicated expressions.
- Use named groups when extracting multiple fields from structured text.
- Use
re.VERBOSE for complex patterns that benefit from comments and formatting.
- Test patterns against valid examples, invalid examples, empty strings, and unexpected characters.
- Be cautious with complex nested quantifiers that may cause excessive backtracking on certain inputs.
- Do not use regex as a substitute for a dedicated parser when processing structured formats such as HTML or JSON.
- Remember that matching a format does not prove that the underlying data is genuine or valid in a business context.
- Compile and reuse a pattern when it improves clarity for repeated operations.
27. Practice Exercises
- Write a regex that extracts all integer numbers from a sentence.
- Use
re.search() to find the word Python in a paragraph.
- Use
re.fullmatch() to check whether a string contains exactly six digits.
- Extract all words from a sentence using
re.findall().
- Replace multiple spaces with one space using
re.sub().
- Split a string using commas, semicolons, and whitespace as delimiters.
- Extract the day, month, and year from a date in
DD-MM-YYYY format using capturing groups.
- Use
re.IGNORECASE to find a word regardless of capitalization.
- Create a compiled pattern for simple employee IDs such as
EMP123.
- Use
re.finditer() to print each number and its starting position.
28. Interview Questions and Answers
Q1. What is a regular expression?
A regular expression is a pattern used to search, match, extract, replace, or split text according to specified rules.
Q2. What is the purpose of Python's re module?
The re module provides functions and pattern objects for working with regular expressions in Python.
Q3. What is the difference between re.search() and re.match()?
re.search() scans the string for a match anywhere, while re.match() checks only at the beginning of the string.
Q4. What is the difference between re.match() and re.fullmatch()?
re.match() checks for a match at the beginning. re.fullmatch() requires the entire string to satisfy the pattern.
Q5. Why are raw strings commonly used in regex patterns?
Raw strings reduce conflicts between Python's string escape processing and the backslashes used in regular expressions.
Q6. What is the difference between re.findall() and re.finditer()?
findall() returns matches in a list, whereas finditer() returns an iterator of match objects that provide matched text and position information.
Q7. What do *, +, and ? mean?
* matches zero or more repetitions, + matches one or more repetitions, and ? matches zero or one repetition.
Q8. What are capturing groups?
Capturing groups use parentheses to isolate parts of a match so that those portions can be retrieved separately.
Q9. What is re.sub() used for?
It replaces portions of a string that match a pattern with specified replacement text.
Q10. What is re.compile()?
It creates a reusable regex pattern object, which can improve code organization when the same pattern is used multiple times.
Q11. What is a word boundary?
The \b sequence matches a position between a word character and a non-word character, or a word character and the beginning or end of the string.
Q12. Can regular expressions fully validate an email address?
A regex can check many common email-like formats, but comprehensive validation involves more rules. Confirming that an address exists or can receive messages requires additional verification.
29. Quick Revision Checklist
- Understand regex patterns and raw strings.
- Recognize metacharacters, character sets, special sequences, and quantifiers.
- Know when to use
search(), match(), and fullmatch().
- Extract matches with
findall() and finditer().
- Replace text with
sub() and split text with split().
- Use capturing groups and named groups to retrieve structured information.
- Understand flags such as
IGNORECASE, MULTILINE, and DOTALL.
- Test patterns against edge cases and avoid unnecessarily complicated expressions.
30. Conclusion
Regular expressions are an important Python skill for searching, validating, extracting, and transforming text. The built-in re module provides flexible functions such as search(), match(), fullmatch(), findall(), sub(), and split() to support these tasks.
By understanding character classes, quantifiers, groups, flags, and common matching functions, developers can write more efficient and maintainable text-processing code. Regular practice with realistic examples will help build confidence in using regex for automation, data cleaning, and application development.
Continue learning: Explore the Python Training Course at JustAcademy, register for a course demo, or visit the JustAcademy homepage.